import { PrismaClient } from '@prisma/client'
import { FamilyMember, FamilyTree, PaginationParams, PaginatedResponse } from '../types'

const prisma = new PrismaClient()

export class FamilyService {
  async getFamilyTrees(userId: number, params: PaginationParams = {}) {
    const { page = 1, limit = 10 } = params
    const offset = (page - 1) * limit
    
    const [trees, total] = await Promise.all([
      prisma.familyTree.findMany({
        where: { createdBy: userId },
        skip: offset,
        take: limit,
        include: {
          rootMember: {
            select: {
              id: true,
              name: true,
              gender: true,
              avatar: true,
            },
          },
          creator: {
            select: {
              id: true,
              username: true,
              nickname: true,
            },
          },
        },
        orderBy: { createdAt: 'desc' },
      }),
      prisma.familyTree.count({
        where: { createdBy: userId },
      }),
    ])

    return {
      data: trees,
      pagination: {
        page,
        limit,
        total,
        pages: Math.ceil(total / limit),
      },
    }
  }

  async createFamilyTree(treeData: Partial<FamilyTree> & { createdBy: number }) {
    return prisma.familyTree.create({
      data: treeData,
      include: {
        rootMember: true,
        creator: {
          select: {
            id: true,
            username: true,
            nickname: true,
          },
        },
      },
    })
  }

  async getFamilyTreeById(id: number) {
    return prisma.familyTree.findUnique({
      where: { id },
      include: {
        rootMember: true,
        creator: {
          select: {
            id: true,
            username: true,
            nickname: true,
          },
        },
        members: {
          include: {
            user: {
              select: {
                id: true,
                username: true,
                nickname: true,
              },
            },
          },
        },
      },
    })
  }

  async updateFamilyTree(id: number, updateData: Partial<FamilyTree>) {
    return prisma.familyTree.update({
      where: { id },
      data: updateData,
      include: {
        rootMember: true,
        creator: {
          select: {
            id: true,
            username: true,
            nickname: true,
          },
        },
      },
    })
  }

  async deleteFamilyTree(id: number) {
    return prisma.familyTree.delete({
      where: { id },
    })
  }

  async getFamilyMembers(params: PaginationParams & { search?: string } = {}) {
    const { page = 1, limit = 10, search } = params
    const offset = (page - 1) * limit
    
    const where = search
      ? {
          OR: [
            { name: { contains: search } },
            { nickname: { contains: search } },
          ],
        }
      : {}

    const [members, total] = await Promise.all([
      prisma.familyMember.findMany({
        where,
        skip: offset,
        take: limit,
        include: {
          user: {
            select: {
              id: true,
              username: true,
              nickname: true,
            },
          },
          parent: {
            select: {
              id: true,
              name: true,
            },
          },
          spouse: {
            select: {
              id: true,
              name: true,
            },
          },
        },
        orderBy: { createdAt: 'desc' },
      }),
      prisma.familyMember.count({ where }),
    ])

    return {
      data: members,
      pagination: {
        page,
        limit,
        total,
        pages: Math.ceil(total / limit),
      },
    }
  }

  async createFamilyMember(memberData: Partial<FamilyMember>) {
    return prisma.familyMember.create({
      data: memberData,
      include: {
        user: {
          select: {
            id: true,
            username: true,
            nickname: true,
          },
        },
        parent: {
          select: {
            id: true,
            name: true,
          },
        },
        spouse: {
          select: {
            id: true,
            name: true,
          },
        },
      },
    })
  }

  async getFamilyMemberById(id: number) {
    return prisma.familyMember.findUnique({
      where: { id },
      include: {
        user: {
          select: {
            id: true,
            username: true,
            nickname: true,
          },
        },
        parent: {
          select: {
            id: true,
            name: true,
          },
        },
        spouse: {
          select: {
            id: true,
            name: true,
          },
        },
        children: {
          select: {
            id: true,
            name: true,
            gender: true,
            avatar: true,
          },
        },
      },
    })
  }

  async updateFamilyMember(id: number, updateData: Partial<FamilyMember>) {
    return prisma.familyMember.update({
      where: { id },
      data: updateData,
      include: {
        user: {
          select: {
            id: true,
            username: true,
            nickname: true,
          },
        },
        parent: {
          select: {
            id: true,
            name: true,
          },
        },
        spouse: {
          select: {
            id: true,
            name: true,
          },
        },
      },
    })
  }

  async deleteFamilyMember(id: number) {
    return prisma.familyMember.delete({
      where: { id },
    })
  }

  async getFamilyTreeStructure(treeId: number) {
    const tree = await prisma.familyTree.findUnique({
      where: { id: treeId },
      include: {
        rootMember: {
          include: {
            children: {
              include: {
                children: {
                  include: {
                    children: true,
                  },
                },
              },
            },
            spouse: true,
          },
        },
      },
    })

    if (!tree) {
      throw new Error('Family tree not found')
    }

    // Build hierarchical structure
    const buildStructure = (member: any, level: number = 0) => {
      return {
        id: member.id,
        name: member.name,
        gender: member.gender,
        avatar: member.avatar,
        generation: member.generation,
        level,
        spouse: member.spouse ? {
          id: member.spouse.id,
          name: member.spouse.name,
          gender: member.spouse.gender,
          avatar: member.spouse.avatar,
        } : null,
        children: member.children?.map((child: any) => buildStructure(child, level + 1)) || [],
      }
    }

    return {
      id: tree.id,
      name: tree.name,
      description: tree.description,
      structure: tree.rootMember ? buildStructure(tree.rootMember) : null,
    }
  }
}